package com.pactera.asmp.server.common.utils;

import cn.hutool.core.io.FileUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.builder.ExcelWriterBuilder;
import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.alibaba.fastjson.JSONObject;
import com.pactera.asmp.server.vo.*;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Title :
 * @Description:
 * @auther wanghao
 * @Date : -
 */
@Slf4j
public class ExcelUtil {

    public static void export(HttpServletResponse response) throws Exception {

        // 注意Map的key必须和模板保持一致,举例是name 和code
        List<Map<String, String>> excelList = new ArrayList<>();
        // 设置响应类型
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        // 设置编码格式
        response.setCharacterEncoding("utf-8");

        long currentTime=System.currentTimeMillis();
        // 设置URLEncoder.encode 防止中文乱码
        String fileName = URLEncoder.encode("人员组织架构模板-" + currentTime, "UTF-8").replaceAll("\\+", "%20");
        // 设置响应头
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");

        // 使用模板填充表格，这里将表格预制到代码resources下面了，可以根据需求预制到其他地方，绝对路径和相对路径都可。
        Resource resource = new ClassPathResource("excelTmp/personTmp.xlsx");
        String templateFileName = resource.getFile().getPath();

        // 生成工作簿对象
        ExcelWriterBuilder workBookWriter = EasyExcel.write(response.getOutputStream())
                .withTemplate(templateFileName);
        // 创建工作表对象
        ExcelWriterSheetBuilder sheet = workBookWriter.sheet(1);
        sheet.doFill(excelList);
    }



    //------------------------------------------------------------------------------

    /**
     * 根据原有的文件流以及sheet0的模板追加sheet并且输出流
     *
     * @param
     * @return byte[] 生成字节流
     * @throws IOException
     */
//    private static byte[] getNewExcelStream(int sheetCount) throws IOException {
//        // 加载模板文件
//        ClassPathResource templateResource = new ClassPathResource("templates/memory-report-template.xlsx");
//        InputStream templateStream = templateResource.getInputStream();
//        XSSFWorkbook  workbook = new XSSFWorkbook(templateStream);
//        for (int i = 0; i < sheetCount; i++) {
//            String sheetName = "sheet"+i;
//            // 复制sheet
////            if (i != 0) {
////                Sheet templateSheet = workbook.getSheet("Ambientlight");
////                Sheet newSheet = workbook.cloneSheet(1, sheetName);
////                workbook.setSheetName(workbook.getSheetIndex(newSheet), sheetName);
////            }
//            workbook.cloneSheet(0, sheetName);
//        }
//        workbook.removeSheetAt(0);
//        ByteArrayOutputStream ops = new ByteArrayOutputStream();
//        workbook.write(ops);
//        byte[] byteArray = ops.toByteArray();
//        // 原文件流后续已不使用，此处关闭
//        templateStream.close();
//        ops.close();
//        return byteArray;
//    }

    public static  File generateExcelFileByTemplate(String templateName,String tempPath, String excelFileName, ExcelStatisticDataVo excelData){
        File excelFile = null;
        try {
            // 创建新的Excel工作簿 POI 的API 用于复制sheet
            ClassPathResource templateResource = new ClassPathResource("templates/"+templateName);
            InputStream templatesInputStream = templateResource.getInputStream();
            // 创建临时导出文件
            excelFile = new File(tempPath + File.separator + excelFileName);
            // easyExcel API 根据is作为模板填充数据，excelFile
            ExcelWriter excelWriter = EasyExcel.write(excelFile).withTemplate(templatesInputStream)
                    .build();
            FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();

            for(ExcelStatisticDataVo.SheetData sheetData : excelData.getSheetDataList()) {
                WriteSheet writeSheet = EasyExcel.writerSheet(sheetData.getSheetName()).head(sheetData.getRecordClass()).build();

//                for(Map<String, Object> rowMap : sheetData.getRowList()) {
//                    excelWriter.fill(rowMap, fillConfig, writeSheet);
//                }
                log.info("sheetData: {}", JSONObject.toJSONString(sheetData.getReportRecords()));
                excelWriter.fill(sheetData.getReportRecords(), fillConfig, writeSheet);
            }
            excelWriter.finish();

        } catch (Exception e) {
            log.error("导出文件时出现异常：{}", e.getMessage(), e);
            //e.printStackTrace();
        }
        return excelFile;
    }

    public static  File generateExcelFileByTemplate(String templateName,String tempPath, String excelFileName, ExcelDataVo excelData, Class recordClass){
        File excelFile = null;
        try {
            // 创建新的Excel工作簿 POI 的API 用于复制sheet
            byte[] newExcelStream = getMoreSheetsExcelTemplateStream("templates/"+templateName,0,excelData.getSheetDataList());
            InputStream templatesInputStream = new ByteArrayInputStream(newExcelStream);

            // 创建临时导出文件
            excelFile = new File(tempPath + File.separator + excelFileName);
            // easyExcel API 根据is作为模板填充数据，excelFile
            ExcelWriter excelWriter = EasyExcel.write(excelFile).withTemplate(templatesInputStream)
                    .build();
            FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();

            for(ExcelDataVo.SheetData sheetData : excelData.getSheetDataList()) {
                WriteSheet writeSheet = EasyExcel.writerSheet(sheetData.getSheetName()).head(recordClass).build();

//                for(Map<String, Object> rowMap : sheetData.getRowList()) {
//                    excelWriter.fill(rowMap, fillConfig, writeSheet);
//                }
                excelWriter.fill(sheetData.getReportRecords(), fillConfig, writeSheet);
            }
            excelWriter.finish();

        } catch (Exception e) {
            log.error("导出文件时出现异常：{}", e.getMessage(), e);
            //e.printStackTrace();
        }
        return excelFile;
    }

    public static  File generateExcelFileByTemplate2(String templateName,String tempPath, String excelFileName, ExcelDataVo excelData, Class recordClass,int cloneIndex){
        File excelFile = null;
        try {
            // 创建新的Excel工作簿 POI 的API 用于复制sheet
            byte[] newExcelStream = getMoreSheetsExcelTemplateStream("templates/"+templateName,cloneIndex,excelData.getSheetDataList());
            InputStream templatesInputStream = new ByteArrayInputStream(newExcelStream);

            // 创建临时导出文件
            excelFile = FileUtil.touch(new File(tempPath + File.separator + excelFileName));
            // easyExcel API 根据is作为模板填充数据，excelFile
            ExcelWriter excelWriter = EasyExcel.write(excelFile).withTemplate(templatesInputStream)
                    .build();
            FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
            WriteSheet writeSheetSt = EasyExcel.writerSheet(excelData.getSheetData().getSheetName()).head(recordClass).build();
            excelWriter.fill(excelData.getSheetData().getReportRecords(), fillConfig, writeSheetSt);

            for(ExcelDataVo.SheetData sheetData : excelData.getSheetDataList()) {
                WriteSheet writeSheet = EasyExcel.writerSheet(sheetData.getSheetName()).head(recordClass).build();

//                for(Map<String, Object> rowMap : sheetData.getRowList()) {
//                    excelWriter.fill(rowMap, fillConfig, writeSheet);
//                }
                excelWriter.fill(sheetData.getReportRecords(), fillConfig, writeSheet);
            }
            excelWriter.finish();

        } catch (Exception e) {
            log.error("导出文件时出现异常：{}", e.getMessage(), e);
            //e.printStackTrace();
        }
        return excelFile;
    }

    private static byte[] getMoreSheetsExcelTemplateStream(String templateFilePath, Integer cloneIndex , List<ExcelDataVo.SheetData> sheetDataList  )  {
        // 加载模板文件
//        ClassPathResource templateResource = new ClassPathResource("templates/memory-report-template.xlsx");
        ClassPathResource templateResource = new ClassPathResource(templateFilePath);
        try (InputStream templateStream = templateResource.getInputStream();
             XSSFWorkbook  workbook = new XSSFWorkbook(templateStream)){
            for (int i = 0; i < sheetDataList.size(); i++) {
                String sheetName = sheetDataList.get(i).getSheetName();
                // 复制sheet
                workbook.cloneSheet(cloneIndex == null?0:cloneIndex, sheetName);
            }
            workbook.removeSheetAt(cloneIndex == null?0:cloneIndex);
            ByteArrayOutputStream ops = new ByteArrayOutputStream();
            workbook.write(ops);
            byte[] byteArray = ops.toByteArray();
            return byteArray;
        } catch (IOException e) {
            log.error("getMoreSheetsExcelTemplateStream error : {} ", e.getMessage());
            return null;
        }

    }


    public static void main(String[] args) {

        ExcelStatisticDataVo excelData = new ExcelStatisticDataVo();
        ExcelStatisticDataVo.SheetData<ReportHmiMemoryRecord> sheetData1 = new ExcelStatisticDataVo.SheetData();
        sheetData1.setSheetName("内存");
        sheetData1.setRecordClass(ReportHmiMemoryRecord.class);
        ReportHmiMemoryRecord reportHmiMemoryRecord = new ReportHmiMemoryRecord();
        reportHmiMemoryRecord.setPackageName("abc");
        reportHmiMemoryRecord.setMemAvg("123");
        reportHmiMemoryRecord.setMemIdle("456");
        reportHmiMemoryRecord.setMemMax("789");
        sheetData1.getReportRecords().add(reportHmiMemoryRecord);

        ExcelStatisticDataVo.SheetData<ReportHmiCpuRecord> sheetData2 = new ExcelStatisticDataVo.SheetData();
        sheetData2.setSheetName("cpu");
        sheetData2.setRecordClass(ReportHmiCpuRecord.class);
        ReportHmiCpuRecord cpuRecord = new ReportHmiCpuRecord();
        cpuRecord.setPackageName("defg");
        cpuRecord.setCpuMin("333");
        cpuRecord.setCpuAvg("444");
        cpuRecord.setCpuMax("555");
        sheetData2.getReportRecords().add(cpuRecord);

        ExcelStatisticDataVo.SheetData<ReportHmiStartRecord> sheetData3 = new ExcelStatisticDataVo.SheetData();
        sheetData3.setSheetName("启动耗时");
        sheetData3.setRecordClass(ReportHmiStartRecord.class);
        ReportHmiStartRecord startRecord = new ReportHmiStartRecord();
        startRecord.setPackageName("xyz");
        startRecord.setColdStart("111");
        startRecord.setWarmStart("N/A");
        startRecord.setHotStart("222");
        sheetData3.getReportRecords().add(startRecord);
        excelData.getSheetDataList().add(sheetData1);
        excelData.getSheetDataList().add(sheetData2);
        excelData.getSheetDataList().add(sheetData3);
        generateExcelFileByTemplate("hmi-report-template.xlsx","F://","test_HMI_report_data.xlsx",excelData);
        //        ExcelDataVo excelData =  new ExcelDataVo();
//        ExcelDataVo.SheetData<ReportMemoryRecord> sheetData1 = new ExcelDataVo.SheetData();
//        ExcelDataVo.SheetData<ReportMemoryRecord> sheetData2 = new ExcelDataVo.SheetData();
//        sheetData1.setSheetName("package001");
//        sheetData2.setSheetName("package002");
//        HashMap<String ,Object> rowMap1 = new HashMap<>();
//        rowMap1.put("timeStamp", "123");
//        rowMap1.put("name","abc");
//        HashMap<String ,Object> rowMap2 = new HashMap<>();
//        rowMap2.put("timeStamp", "456");
//        rowMap2.put("name","xys");
//        sheetData1.getRowList().add(rowMap1);
//        sheetData2.getRowList().add(rowMap2);
////        sheetData1.getRowList().add(rowMap2);
//        ReportMemoryRecord reportMemoryRecord1 = new ReportMemoryRecord();
//        ReportMemoryRecord reportMemoryRecord2 = new ReportMemoryRecord();
//        reportMemoryRecord1.setName("111111");
//        reportMemoryRecord1.setPid("pppp");
//        reportMemoryRecord2.setName("22222");
//        sheetData1.getReportRecords().add(reportMemoryRecord1);
//        sheetData1.getReportRecords().add(reportMemoryRecord2);
//        sheetData2.getReportRecords().add(reportMemoryRecord1);
//        excelData.getSheetDataList().add(sheetData1);
//        excelData.getSheetDataList().add(sheetData2);
//        generateExcelFileByTemplate("memory-report-template.xlsx","F://","test_memory_report_data.xlsx",excelData,ReportMemoryRecord.class);
//=========================================================
//        int sheetCount = 2;
//        try {
//            // 创建新的Excel工作簿 POI 的API 用于复制sheet
//            byte[] newExcelStream = getNewExcelStream(sheetCount);
//            InputStream asInputStream = new ByteArrayInputStream(newExcelStream);
//
//            File temporaryFile = File.createTempFile("test_Performance_data", ".xlsx", new File("F://"));
//            // easyExcel API 根据is作为模板填充数据，并写入临时文件temporaryFile
//            ExcelWriter excelWriter = EasyExcel.write(temporaryFile).withTemplate(asInputStream)
//                    .build();
//            FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
//
//
//
//            String sheetName1 = "sheet0";
//            String sheetName2= "sheet1";
//            EasyExcel.writerSheet();
//            WriteSheet writeSheet = EasyExcel.writerSheet(sheetName1).build();
//            //System.out.println(writeSheet.getSheetName()+" "+writeSheet.getSheetNo());
//            Map<String, Object> map = new HashMap<>();
//            map.put("name", "123");
//            excelWriter.fill(map, writeSheet);
//
//            WriteSheet writeSheet2 = EasyExcel.writerSheet(sheetName2).head(ReportMemoryRecord.class).build();
//            if(writeSheet2 == null){
//                System.out.println("is null i="+1);
//            }
//            Map<String, Object> map2 = new HashMap<>();
//            map2.put("timeStamp", "123");
//
//
//            //excelWriter.fill(list, fillConfig, writeSheet2);
//            excelWriter.fill(map2, fillConfig, writeSheet2);
//
//            excelWriter.finish();
//
//        } catch (Exception e) {
//            log.error("表决模板导出文件时出现异常：{}", e.getMessage(), e);
//            e.printStackTrace();
//        }
    }


}
